<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace app\common\model;

use buwang\base\BaseModel;
use buwang\traits\JwtTrait;

/**
 * 成员应用表
 * Class
 * @package app\manage\model
 */
class User extends BaseModel
{
    use JwtTrait;

    /**
     * 判断invite_code用户是否存在
     *
     */
    public static function isInvite($invite_code,$member_miniapp_id=null){
        if(empty($invite_code)){
            return;
        }
        $id = de_code(strtoupper($invite_code));
        $self = new self;
        if($member_miniapp_id)$self = $self->where('member_miniapp_id',$member_miniapp_id);
        $is_invite = $self->where(['id' => $id])->field('id')->find();
        return empty($is_invite) ? 0 : $is_invite['id'];
    }

    public static function checkPassword($password, $safePassword)
    {
        //TODO：验证安全密码
        if (password_verify(md5($password), $safePassword)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 驗證用戶信息
     *
     */
    public static function validateUser($username, $password)
    {
        //判断用户是否存在
        $userInfo = self::where('username|mobile', $username)->find();

        if (!$userInfo) return self::setError('用户名或密码错误');
        if ($userInfo['status'] == 0) return self::setError('账号已被封禁无法登陆');
        //得到加密后的密码
        if (!self::checkPassword($password, $userInfo['password'])) return self::setError('用户名或密码错误');
        return $userInfo;
    }

    /**
     * 登錄用戶User
     * @param $user
     * @param $scopes
     * @param bool $trans
     * @return array|bool
     */
    public static function loginUser($user, $scopes, $trans = false)
    {
        if (!in_array($scopes, ['mini_program', 'app', 'h5', 'official'])) return self::setError('scopes類型錯誤');
        if ($trans) {
            self::startTrans();
        }
        $res = $res1 = $res2 = $tokenInfo = true;
        try {
            $data = [
                'id' => $user['id'],
                'nickname' => $user['nickname'] ?: '',
                'mobile ' => $user['mobile'] ?: '',
            ];
            $tokenInfo = self::getAccessToken($data, $scopes);
            //存儲token相关信息
            // $res2 = Token::updateToken($user['id'], $tokenInfo['token'], 'admin');
            //更新用户登录信息
            $user->login_time = time();
            $user->login_ip = request()->ip();
            $res1 = $user->save();

            $res = $res1 && $res2 && $tokenInfo && true;
            if ($trans) {
                self::checkTrans($res);
            }
            // TODO 用户登录成功后事件
            event('UserLoginSuccess', [$user, $scopes]);
        } catch (\Exception $e) {
            if ($trans) {
                self::rollback();
            }
            return self::setError($e->getMessage());
        }
        if (!$tokenInfo) return self::setError('获取AccessToken或存储失败');
        if (!$res1) return self::setError('更新用户登录信息失败');
        if (!$res2) return self::setError('更新用户验证信息失败');
        return $tokenInfo;
    }

    /**
     * 通过微信注册或更新
     * @param array $wechat
     * @param int $is_miniapp true小程序  fasle公众号
     * @return 成功后返回用户的ID
     */
    public static function wechatReg(array $wechat, $is_miniapp = true)
    {
        //参数
        $data = [];
        $updata = [];
        $data['member_miniapp_id'] = $wechat['miniapp_id'];//程序的主键ID 不是小程序的APPID
        $data['nickname'] = $wechat['nickname'];
        $data['avatar'] = $wechat['avatar'];
        $data['official_uid'] = $wechat['official_uid'];
        $data['miniapp_uid'] = $wechat['miniapp_uid'];
        $data['unionid'] = $wechat['unionid'];//unionid
        $data['login_time'] = time();
        $data['update_time'] = time();
        $data['login_ip'] = request()->ip();
        //查询用户类型$condition查询条件
        $condition['member_miniapp_id'] = $wechat['miniapp_id'];
        if ($is_miniapp) {//如果是小程序用户的注册
            $data['session_key'] = $wechat['session_key'];
            $updata['session_key'] = $wechat['session_key'];
            $condition['miniapp_uid'] = $data['miniapp_uid'];
        } else {//公众号用户注册
            $condition['official_uid'] = $data['official_uid'];//公众号openid
        }
        $info = self::where($condition)->find();//先查询下有没有
        if (empty($info)) {//新注册用户
            // $data['create_time'] = time();
            $is_insert = true;
            //如果用户先进入公众号,后进入小程序保证账户同步
            if ($is_miniapp && !empty($data['official_uid'])) {
                $official_info = self::where(['member_miniapp_id' => $wechat['miniapp_id'], 'official_uid' => $data['official_uid']])->find();
                if ($official_info) {
                    $is_insert = false;
                    $last_id = $official_info['id'];
                    self::update(['id' => $last_id, 'miniapp_uid' => $data['miniapp_uid']]);
                }
            }
            //判断是否需要插入数据
            if ($is_insert) {
                $data['create_time'] = time();
                $is_invite = $wechat['invite_code'] ? self::isInvite($wechat['invite_code'],$wechat['miniapp_id']) : false;  //查邀请码是否有效
                if ($is_invite) {
                    $data['pid'] = de_code($wechat['invite_code']);//注册用户加入上级推荐人
                }
                $last_id = self::insertGetId($data);
                if ($last_id) {
                    self::where('id', $last_id)->data(['invite_code' => en_code($last_id)])->update();//每个人的邀请码是根据ID生成的可解密code
                    /**-------------20200910 jyk 注册成功后创建对应应用的用户副表 start-----------------**/
                    if ($is_miniapp) {
                        $type = 'mini_program';//小程序
                    } else {
                        $type = 'official';//公众号
                    }
                    $user = self::find($last_id);
                    // TODO 用户注册成功后事件
                    event('UserRegisterSuccess', [$user, $type]);
                    /**-------------20200910 jyk 注册成功后创建对应应用的用户副表 end-----------------**/
                }
//                //添加用户邀请来源
//                if(!empty($wechat['invite_code'])){
//                    $is_invite = model('User')->isInvite($wechat['invite_code']);  //临时解决邀请问题
//                    if($is_invite){
//                        model('UserLevel')->addLevel($last_id,$is_invite);
//                    }
//                }
            }
        } else { //老用户更新
            $updata['nickname'] = $wechat['nickname'];
            $updata['avatar'] = $wechat['avatar'];
            $updata['login_time'] = time();
            $updata['login_ip'] = request()->ip();
            $updata['session_key'] = $wechat['session_key'];
            if ($is_miniapp && !empty($data['official_uid'])) {
                $updata['official_uid'] = $data['official_uid'];
            }
            $is_invite = $wechat['invite_code'] ? self::isInvite($wechat['invite_code'],$wechat['miniapp_id']) : false;  //查邀请码是否有效
            if ($is_invite) {
                if(!$info['pid'])$updata['pid'] = de_code($wechat['invite_code']);//注册用户加入上级推荐人
            }


            self::where(['id' => $info->id])->data($updata)->update();
            $last_id = $info->id;

            /**-------------20200910 jyk 更新成功后调用事件 start-----------------**/
            if ($is_miniapp) {
                $type = 'mini_program';//小程序
            } else {
                $type = 'official';//公众号
            }
            $user = self::find($info->id);
            // TODO 用户更新成功后事件
            event('UserUpdateSuccess', [$user, $type]);
            /**-------------20200910 jyk 更新成功后调用事件 end-----------------**/
        }
        return $last_id;
    }

    /**
     * TODO更新安全密码
     * @param array $param 更新的用户信息
     */
    public static function updateSafePasspord(int $uid, string $safe_password)
    {
        $data['safe_password'] = password_hash(md5($safe_password), PASSWORD_DEFAULT);
        return self::where(['id' => $uid])->update($data);
    }

    /**
     * 修改登录密码
     * @access public
     */
    public function upLoginPasspowrd(int $uid, string $password)
    {
        $data['password'] = password_hash(md5($password), PASSWORD_DEFAULT);
        return self::where(['id' => $uid])->update($data);
    }

    /**
     * 锁定用户
     * @param integer $id
     */
    public static function lockUser(int $appid, int $id)
    {
        $result = self::where(['member_miniapp_id' => $appid, 'id' => $id])->find();
        if ($result->is_delete >= 1) {
            return FALSE;
        }
        $result->status = $result->status ? 0 : 1;
        return $result->save();
    }

    /**
     * 登录用户ID
     */
    public static function edit(array $data, int $id)
    {
        return User::where(['id' => $id])->update($data);
    }

    /**
     * 作废
     * @param integer $id
     */
    public static function isDelete(int $appid, int $id)
    {
        $result = self::where(['member_miniapp_id' => $appid, 'id' => $id])->find();
        if ($result->is_delete >= 1) {
            return FALSE;
        }
        $result->status = 1;
        $result->is_delete = 1;
        $result->mobile = '';
        $result->unionid = '';
        $result->official_uid = '';
        $result->miniapp_uid = '';
        return $result->save();
    }
}